﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text;

#if DEBUG

using NUnit.Core;

namespace STCommon.NUnit
{
    class NUnitTestManagerProxy : INUnitTestManager
    {
        public NUnitTestManagerProxy(object testManager)
        {
            if (testManager == null)
            {
                throw new Exception("Invalid provider pointer");
            }

            Type providerType = testManager.GetType();

            m_TestManager = testManager;

            m_TestAssemblies = providerType.GetProperty("TestAssemblies", typeof(IList<string>));
            m_RegisterTestAssemblyMethod = providerType.GetMethod("RegisterTestAssembly", new Type[] { typeof(string) });
            m_ClearAssembliesMethod = providerType.GetMethod("ClearAssemblies");
            m_RunTests1Method = providerType.GetMethod("RunTests", new Type[] { typeof(EventListener) });
            m_RunTests2Method = providerType.GetMethod("RunTests", new Type[] { typeof(string), typeof(EventListener) });
            m_RunTests3Method = providerType.GetMethod("RunTests", new Type[] { typeof(List<string>), typeof(EventListener) });
            m_TestAssemblyRegisteredEvent = providerType.GetEvent("TestAssemblyRegistered");

            if (m_TestAssemblies == null ||
                m_RegisterTestAssemblyMethod == null ||
                m_ClearAssembliesMethod == null ||
                m_RunTests1Method == null ||
                m_RunTests2Method == null ||
                m_RunTests3Method == null ||
                m_TestAssemblyRegisteredEvent == null)
            {
                throw new Exception("Object doesn't implement INUnitTestManager interface");
            }

            m_TestAssemblyRegisteredEvent.AddEventHandler(m_TestManager, Delegate.CreateDelegate(typeof(PropertyChangedEventHandler), this, "DataTrackChangedEventHandler"));
        }

#region INUnitTestManager Members

        public void RegisterTestAssembly(string assemblyPath)
        {
            m_RegisterTestAssemblyMethod.Invoke(m_TestManager, new object[] { assemblyPath });
        }

        public void ClearAssemblies()
        {
            m_ClearAssembliesMethod.Invoke(m_TestManager, null);
        }

        public void RunTests(EventListener listener)
        {
            m_RunTests1Method.Invoke(m_TestManager, new object[] { listener });
        }

        public void RunTests(string assembly, EventListener listener)
        {
            m_RunTests2Method.Invoke(m_TestManager, new object[] { assembly, listener });
        }

        public void RunTests(List<string> assemblies, EventListener listener)
        {
            m_RunTests3Method.Invoke(m_TestManager, new object[] { assemblies, listener });
        }

        public IList<string> TestAssemblies
        {
            get { return (IList<string>)m_TestAssemblies.GetValue(m_TestManager, null); }
        }

        public event PropertyChangedEventHandler TestAssemblyRegistered;

#endregion

        private void DataTrackChangedEventHandler(object sender, PropertyChangedEventArgs e)
        {
            if (TestAssemblyRegistered != null)
            {
                TestAssemblyRegistered(this, e);
            }
        }

        private object m_TestManager;
        private PropertyInfo m_TestAssemblies = null;
        private MethodInfo m_RegisterTestAssemblyMethod = null;
        private MethodInfo m_ClearAssembliesMethod = null;
        private MethodInfo m_RunTests1Method = null;
        private MethodInfo m_RunTests2Method = null;
        private MethodInfo m_RunTests3Method = null;
        private EventInfo m_TestAssemblyRegisteredEvent = null;
    }
}

#endif
